package com.zjcloud.framework.config;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * MyBatis配置类
 * 
 * @author ruoyi
 */
@Configuration
public class MyBatisConfig
{
    private static final Logger log = LoggerFactory.getLogger(MyBatisConfig.class);
    /**
     * 配置jwgl模块的Mapper扫描
     */
    @Bean
    public MapperScannerConfigurer jwglMapperScannerConfigurer()
    {
        MapperScannerConfigurer configurer = new MapperScannerConfigurer();
        configurer.setBasePackage("com.zjcloud.jwgl.mapper");
        configurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
        configurer.setNameGenerator((beanName, beanDefinition) -> "jwgl" + beanName);
        return configurer;
    }

    /**
     * 配置academic模块的Mapper扫描
     */
    @Bean
    public MapperScannerConfigurer academicMapperScannerConfigurer()
    {
        MapperScannerConfigurer configurer = new MapperScannerConfigurer();
        configurer.setBasePackage("com.zjcloud.academic.mapper");
        configurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
        configurer.setNameGenerator((beanName, beanDefinition) -> "academic" + beanName);
        return configurer;
    }

    /**
     * 配置SqlSessionFactory
     */
    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception
    {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setCallSettersOnNulls(true);
        configuration.setMapUnderscoreToCamelCase(true);
        
        // 处理类型别名
        org.apache.ibatis.type.TypeAliasRegistry typeAliasRegistry = configuration.getTypeAliasRegistry();
        
        // 为JwglScheduleTask类设置特殊别名
        try {
            Class<?> jwglScheduleTaskClass = Class.forName("com.zjcloud.jwgl.domain.JwglScheduleTask");
            typeAliasRegistry.registerAlias("JwglScheduleTask", jwglScheduleTaskClass);
        } catch (ClassNotFoundException e) {
            // 如果类不存在，忽略错误
        }
        
        // 为AcScheduleTask类设置特殊别名
        try {
            Class<?> acScheduleTaskClass = Class.forName("com.zjcloud.academic.domain.AcScheduleTask");
            typeAliasRegistry.registerAlias("AcademicScheduleTask", acScheduleTaskClass);
            typeAliasRegistry.registerAlias("AcScheduleTask", acScheduleTaskClass);
        } catch (ClassNotFoundException e) {
            // 如果类不存在，忽略错误
        }
        
        // 为AcSemester类设置特殊别名
        try {
            Class<?> acSemesterClass = Class.forName("com.zjcloud.academic.domain.AcSemester");
            typeAliasRegistry.registerAlias("AcSemester", acSemesterClass);
            log.info("Registered alias: AcSemester -> {}", acSemesterClass.getName());
        } catch (ClassNotFoundException e) {
            log.error("Failed to register alias: AcSemester", e);
        }
        
        // 注册AcScheduleStatistics类别名
            try {
                Class<?> acScheduleStatisticsClass = Class.forName("com.zjcloud.jwgl.domain.AcScheduleStatistics");
                typeAliasRegistry.registerAlias("AcScheduleStatistics", acScheduleStatisticsClass);
                log.info("成功注册AcScheduleStatistics类别名: AcScheduleStatistics");
            } catch (ClassNotFoundException e) {
                log.error("注册AcScheduleStatistics类别名失败: {}", e.getMessage());
            }
        
        // 为AcConstraintType类设置特殊别名
        try {
            Class<?> acConstraintTypeClass = Class.forName("com.zjcloud.jwgl.domain.AcConstraintType");
            typeAliasRegistry.registerAlias("AcConstraintType", acConstraintTypeClass);
            log.info("Registered alias: AcConstraintType -> {}", acConstraintTypeClass.getName());
        } catch (ClassNotFoundException e) {
            log.error("Failed to register alias: AcConstraintType", e);
        }
        
        // 为AcSchoolInfo类设置特殊别名
        try {
            Class<?> acSchoolInfoClass = Class.forName("com.zjcloud.jwgl.domain.AcSchoolInfo");
            typeAliasRegistry.registerAlias("AcSchoolInfo", acSchoolInfoClass);
            log.info("Registered alias: AcSchoolInfo -> {}", acSchoolInfoClass.getName());
        } catch (ClassNotFoundException e) {
            log.error("Failed to register alias: AcSchoolInfo", e);
        }
        
        // 为ScScheduleResult类设置特殊别名
        try {
            Class<?> scScheduleResultClass = Class.forName("com.zjcloud.jwgl.domain.ScScheduleResult");
            typeAliasRegistry.registerAlias("JwglScScheduleResult", scScheduleResultClass);
        } catch (ClassNotFoundException e) {
            // 如果类不存在，忽略错误
        }
        
        // 为schedule模块的ScScheduleResult类设置特殊别名
        try {
            Class<?> scheduleScScheduleResultClass = Class.forName("com.zjcloud.schedule.domain.ScScheduleResult");
            typeAliasRegistry.registerAlias("ScheduleScScheduleResult", scheduleScScheduleResultClass);
        } catch (ClassNotFoundException e) {
            // 如果类不存在，忽略错误
        }
        
        // 为SysConfig类设置特殊别名
        try {
            Class<?> sysConfigClass = Class.forName("com.zjcloud.system.domain.SysConfig");
            typeAliasRegistry.registerAlias("SysConfig", sysConfigClass);
        } catch (ClassNotFoundException e) {
            // 如果类不存在，忽略错误
        }
        
        // 为SysDept类设置特殊别名
        try {
            Class<?> sysDeptClass = Class.forName("com.zjcloud.common.core.domain.entity.SysDept");
            typeAliasRegistry.registerAlias("SysDept", sysDeptClass);
        } catch (ClassNotFoundException e) {
            // 如果类不存在，忽略错误
        }
        
        // 为SysDictData类设置特殊别名
        try {
            Class<?> sysDictDataClass = Class.forName("com.zjcloud.common.core.domain.entity.SysDictData");
            typeAliasRegistry.registerAlias("SysDictData", sysDictDataClass);
            log.info("Successfully registered alias: SysDictData -> com.zjcloud.common.core.domain.entity.SysDictData");
        } catch (ClassNotFoundException e) {
            log.error("Failed to register alias: SysDictData", e);
        }
        
        // 注册SysDictType别名
            try {
                Class<?> sysDictTypeClass = Class.forName("com.zjcloud.common.core.domain.entity.SysDictType");
                typeAliasRegistry.registerAlias("SysDictType", sysDictTypeClass);
                log.info("Successfully registered alias: SysDictType -> com.zjcloud.common.core.domain.entity.SysDictType");
            } catch (ClassNotFoundException e) {
                log.error("Failed to register alias: SysDictType", e);
            }
            
            // 注册SysLogininfor别名
            try {
                Class<?> sysLogininforClass = Class.forName("com.zjcloud.system.domain.SysLogininfor");
                typeAliasRegistry.registerAlias("SysLogininfor", sysLogininforClass);
                log.info("Successfully registered alias: SysLogininfor -> com.zjcloud.system.domain.SysLogininfor");
            } catch (ClassNotFoundException e) {
                log.error("Failed to register alias: SysLogininfor", e);
            }
            
            // 注册SysMenu别名
            try {
            Class<?> sysMenuClass = Class.forName("com.zjcloud.common.core.domain.entity.SysMenu");
            typeAliasRegistry.registerAlias("SysMenu", sysMenuClass);
            log.info("Registered alias: SysMenu -> {}", sysMenuClass.getName());
        } catch (ClassNotFoundException e) {
            log.error("Failed to register alias: SysMenu", e);
        }
        
        try {
            Class<?> sysNoticeClass = Class.forName("com.zjcloud.system.domain.SysNotice");
            typeAliasRegistry.registerAlias("SysNotice", sysNoticeClass);
            log.info("Registered alias: SysNotice -> {}", sysNoticeClass.getName());
        } catch (ClassNotFoundException e) {
            log.error("Failed to register alias: SysNotice", e);
        }
        
        try {
            Class<?> sysOperLogClass = Class.forName("com.zjcloud.system.domain.SysOperLog");
            typeAliasRegistry.registerAlias("SysOperLog", sysOperLogClass);
            log.info("Registered alias: SysOperLog -> {}", sysOperLogClass.getName());
        } catch (ClassNotFoundException e) {
            log.error("Failed to register alias: SysOperLog", e);
        }
        
        try {
            Class<?> sysPostClass = Class.forName("com.zjcloud.system.domain.SysPost");
            typeAliasRegistry.registerAlias("SysPost", sysPostClass);
            log.info("Registered alias: SysPost -> {}", sysPostClass.getName());
        } catch (ClassNotFoundException e) {
            log.error("Failed to register alias: SysPost", e);
        }
        
        try {
            Class<?> sysRoleDeptClass = Class.forName("com.zjcloud.system.domain.SysRoleDept");
            typeAliasRegistry.registerAlias("SysRoleDept", sysRoleDeptClass);
            log.info("Registered alias: SysRoleDept -> {}", sysRoleDeptClass.getName());
        } catch (ClassNotFoundException e) {
            log.error("Failed to register alias: SysRoleDept", e);
        }
        
        try {
            Class<?> sysUserClass = Class.forName("com.zjcloud.common.core.domain.entity.SysUser");
            typeAliasRegistry.registerAlias("SysUser", sysUserClass);
            log.info("Registered alias: SysUser -> {}", sysUserClass.getName());
        } catch (ClassNotFoundException e) {
            log.error("Failed to register alias: SysUser", e);
        }
        
        try {
            Class<?> sysRoleClass = Class.forName("com.zjcloud.common.core.domain.entity.SysRole");
            typeAliasRegistry.registerAlias("SysRole", sysRoleClass);
            log.info("Registered alias: SysRole -> {}", sysRoleClass.getName());
        } catch (ClassNotFoundException e) {
            log.error("Failed to register alias: SysRole", e);
        }
        
        try {
            Class<?> sysRoleMenuClass = Class.forName("com.zjcloud.system.domain.SysRoleMenu");
            typeAliasRegistry.registerAlias("SysRoleMenu", sysRoleMenuClass);
            log.info("Registered alias: SysRoleMenu -> {}", sysRoleMenuClass.getName());
        } catch (ClassNotFoundException e) {
            log.error("Failed to register alias: SysRoleMenu", e);
        }
        
        try {
    Class<?> sysUserPostClass = Class.forName("com.zjcloud.system.domain.SysUserPost");
    typeAliasRegistry.registerAlias("SysUserPost", sysUserPostClass);
    log.info("Registered alias: SysUserPost -> {}", sysUserPostClass.getName());
} catch (ClassNotFoundException e) {
    log.error("Failed to register alias: SysUserPost", e);
}

try {
    Class<?> sysUserRoleClass = Class.forName("com.zjcloud.system.domain.SysUserRole");
    typeAliasRegistry.registerAlias("SysUserRole", sysUserRoleClass);
    log.info("Registered alias: SysUserRole -> {}", sysUserRoleClass.getName());
} catch (ClassNotFoundException e) {
    log.error("Failed to register alias: SysUserRole", e);
}

try {
    Class<?> sysJobLogClass = Class.forName("com.zjcloud.quartz.domain.SysJobLog");
    typeAliasRegistry.registerAlias("SysJobLog", sysJobLogClass);
    log.info("Registered alias: SysJobLog -> {}", sysJobLogClass.getName());
} catch (ClassNotFoundException e) {
    log.error("Failed to register alias: SysJobLog", e);
}

try {
    Class<?> sysJobClass = Class.forName("com.zjcloud.quartz.domain.SysJob");
    typeAliasRegistry.registerAlias("SysJob", sysJobClass);
    log.info("Registered alias: SysJob -> {}", sysJobClass.getName());
} catch (ClassNotFoundException e) {
    log.error("Failed to register alias: SysJob", e);
}
        
        sessionFactory.setConfiguration(configuration);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath*:mapper/**/*Mapper.xml"));
        
        return sessionFactory.getObject();
    }
}